Skip to content

WIP: stock chat rework - #101

Closed
blattersturm wants to merge 7 commits into
citizenfx:masterfrom
blattersturm:feature/chat-rework
Closed

WIP: stock chat rework#101
blattersturm wants to merge 7 commits into
citizenfx:masterfrom
blattersturm:feature/chat-rework

Conversation

@blattersturm

Copy link
Copy Markdown
Contributor

Around 2 years since the initial design document, here is some progress on reworking the existing chat resource.

A few notes:

Refactored building

It's now a TypeScript resource using Webpack/Yarn. The embedded templates have been replaced with .vue files including a separate code-behind .ts file to help with VSCode tooling support.

Building

There's no integration for resource builders yet, you'll have to build it yourself before running:

yarn
node_modules\.bin\webpack --progress

Chat modes

The most significant feature added, there's now support for chat modes.

modes

Example script:

-- server
exports.chat:registerMode({
    name = 'local',
    displayName = 'Local',
    color = '#09F',
    cb = function(source, message, cbs)
        local players = {}
        local selfCoords = GetEntityCoords(GetPlayerPed(source))

        for _, id in ipairs(GetPlayers()) do
            if #(GetEntityCoords(GetPlayerPed(id)) - selfCoords) < 200.0 then
                table.insert(players, id)
            end
        end

        cbs.updateMessage({
            template = '<b>^#FF9800[{{zone}}]^7</b> {}',
            params = { zone = zones[source] or 'Pacific Ocean' }
        })

        cbs.setRouting(players)
    end
})

exports.chat:registerMode({
    name = 'ooc',
    displayName = 'OOC',
    color = '#f0f',
    cb = function(source, message, cbs)
        cbs.updateMessage({
            args = { message.args[1], '((' .. message.args[2] .. '))' }
        })
    end
})

exports.chat:registerMode({
    name = 'long',
    displayName = 'really quite a long mode name or something of such sort',
    color = '#696',
    cb = function(source, message, cbs)
        cbs.updateMessage({
            args = { message.args[1], message.args[2]:reverse() }
        })
    end
})

Similarly, there's hooks:

-- server
exports.chat:registerMessageHook(function(source, message, cbs)
    cbs.updateMessage({
        template = '{}^7 ({{role}})',
        params = { role = 'MADMIN' }
    })
end)

... and a way to disable global chat if you're so inclined:

-- client
SetTimeout(500,
function()
    TriggerEvent('chat:removeMode', 'all')
end)

These modes are toggled between using TAB.

Other tiny changes

  • Color codes: ~r~ etc. have some minimal support, and you can add ^#0099FF colors as well now.
  • A few events have been moved to exports, and now there's both exports and events for them.
  • There's convars to disable join/quit messages now.
  • Join messages are now triggered a bit earlier instead of on chat load.
  • A bit of theme incompatibility. chat-theme-gtao has been updated, however.
  • Fixed chat input box height being broken on first open.
  • A Battlefield-style key bind to toggle chat hiding (L by default) with associated command.
  • Messages can now have named {{blah}} placeholders which take from params instead of args.

Gotchas

  • No builders yet.
  • Hooks can't get the mode yet.
  • Registered modes don't persist well if chat is restarted.
  • Theme template replacements and config.js settings are not supported yet.
  • Not all game colors are added for ~ stuff yet.
  • Maybe there's new HTML injection issues - this needs checking.
  • Perhaps some edge cases with chat hiding?

This is unfinished and a bunch of other features ought to be added at a later time.

@ekralc

ekralc commented Apr 12, 2020

Copy link
Copy Markdown

This is amazing!

How about a way to determine which modes an individual player can cycle through? For instance, if you had an 'admin chat' mode that only accepts messages from and routes to certain players, there'd be no need for normal players to cycle through this mode that's useless to them.

Edit: Never mind, you could just do the above using the chat:removeMode event.

@blattersturm

Copy link
Copy Markdown
Contributor Author

How about a way to control access to a mode? For instance, if you wanted an 'admin chat' mode that only routes to certain players, you wouldn't want players to have to cycle through this mode that's useless to them.

Added to the PR:

exports.chat:registerMode({
    name = 'admin',
    displayName = 'Admin',
    color = '#f00',
    seObject = 'chat.admin',
    cb = function(source, message, cbs)
        cbs.updateMessage({
            template = '<b>^#FF1200[ADMIN CHAT]^7</b> {}'
        })

        cbs.setSeObject('chat.admin')
    end
})

This will show and route only to people holding the chat.admin privilege.

@Nexxed

Nexxed commented Apr 19, 2020

Copy link
Copy Markdown

A couple of ideas:

  • An export to edit a pre-existing chat mode (for, as an example, setting a new display name)
  • An export/event to toggle a chat mode from being enabled/disabled

@PichotM

PichotM commented Apr 23, 2020

Copy link
Copy Markdown

As messages with commands start with '/' hooks don't run with them.
The thing is people can fake an non existing command like / hello i can speak and be able to bypass everything.

@spoty123

Copy link
Copy Markdown

Suggestion for a new feature:

Registering suggestions via server-side scripts, you can find more info in #148.

@blattersturm

Copy link
Copy Markdown
Contributor Author

This has been merged a while ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants